/*
 * Copyright (c) 2020-2021, SERI Development Team
 *
 * SPDX-License-Identifier: Apache-2.0
 *
 * Change Logs:
 * Date           Author       Notes
 * 2021-10-29     Lyons        first version
 */

.section .text

.global interrupt_enable
.align 2
interrupt_disable:
    csrrci  a0, mstatus, 8
    ret

.global interrupt_disable
.align 2
interrupt_enable:
    csrw    mstatus, a0
    ret

/* Macro for saving task context */
.macro save_context
    addi    sp, sp, -32*4

    sw      x1,   1*4(sp)
    
    csrr    x1, mepc
    sw      x1,   0*4(sp)
   
    li      x1, 0x0088
    sw      x1,   2*4(sp)

    sw      x4,   4*4(sp)
    sw      x5,   5*4(sp)
    sw      x6,   6*4(sp)
    sw      x7,   7*4(sp)
    sw      x8,   8*4(sp)
    sw      x9,   9*4(sp)
    sw      x10, 10*4(sp)
    sw      x11, 11*4(sp)
    sw      x12, 12*4(sp)
    sw      x13, 13*4(sp)
    sw      x14, 14*4(sp)
    sw      x15, 15*4(sp)
    sw      x16, 16*4(sp)
    sw      x17, 17*4(sp)
    sw      x18, 18*4(sp)
    sw      x19, 19*4(sp)
    sw      x20, 20*4(sp)
    sw      x21, 21*4(sp)
    sw      x22, 22*4(sp)
    sw      x23, 23*4(sp)
    sw      x24, 24*4(sp)
    sw      x25, 25*4(sp)
    sw      x26, 26*4(sp)
    sw      x27, 27*4(sp)
    sw      x28, 28*4(sp)
    sw      x29, 29*4(sp)
    sw      x30, 30*4(sp)
    sw      x31, 31*4(sp)
.endm

/* Macro for restoring task context */
.macro restore_context
    lw      x1,   0*4(sp)
    csrw    mepc, x1
    
    lw      x1,   1*4(sp)

    li      t0, 0x1800
    csrw    mstatus, t0
    lw      t0,   2*4(sp)
    csrs    mstatus, t0

    lw      x4,   4*4(sp)
    lw      x5,   5*4(sp)
    lw      x6,   6*4(sp)
    lw      x7,   7*4(sp)
    lw      x8,   8*4(sp)
    lw      x9,   9*4(sp)
    lw      x10, 10*4(sp)
    lw      x11, 11*4(sp)
    lw      x12, 12*4(sp)
    lw      x13, 13*4(sp)
    lw      x14, 14*4(sp)
    lw      x15, 15*4(sp)
    lw      x16, 16*4(sp)
    lw      x17, 17*4(sp)
    lw      x18, 18*4(sp)
    lw      x19, 19*4(sp)
    lw      x20, 20*4(sp)
    lw      x21, 21*4(sp)
    lw      x22, 22*4(sp)
    lw      x23, 23*4(sp)
    lw      x24, 24*4(sp)
    lw      x25, 25*4(sp)
    lw      x26, 26*4(sp)
    lw      x27, 27*4(sp)
    lw      x28, 28*4(sp)
    lw      x29, 29*4(sp)
    lw      x30, 30*4(sp)
    lw      x31, 31*4(sp)

    addi    sp, sp, 32*4
.endm

.global trap_entry
.align 2
trap_entry:
    j       vector_handler

vector_handler:
_save:
    save_context

#ifdef OS_ENABLE_RT_THREAD
    la      t0, rt_interrupt_nest
    li      t1, 1
    sb      t1, 0(t0)
#endif

    csrr    a0, mcause
    csrr    a1, mepc

    srli    t0, a0, 31
    beq     t0, a0, _is_exception

    csrw    mscratch, sp
    mv      sp, gp
    
    call    trap_handler

    csrr    sp, mscratch

    j       _is_interrupt

_is_exception:
    addi    a1, a1, 4
    csrw    mepc, a1

_is_interrupt:

#ifdef OS_ENABLE_RT_THREAD
    la      s0, rt_thread_switch_interrupt_flag
    lw      s2, 0(s0)
    beqz    s2, _restore
    sw      zero, 0(s0)

    la      s0, rt_interrupt_from_thread
    lw      s1, 0(s0)
    sw      sp, 0(s1)

    la      s0, rt_interrupt_to_thread
    lw      s1, 0(s0)
    lw      sp, 0(s1)
#endif

_restore:
#ifdef OS_ENABLE_RT_THREAD
    la      t0, rt_interrupt_nest
    sb      zero, 0(t0)
#endif

    restore_context

    mret

_nop_list:
    nop
    nop
    nop

.weak trap_handler
trap_handler:
    ret
